<!-- 静态页面刘浩搭建
author 刘浩
date 7月28
-->
<template>
  <div class="container">
    <div style="float: left; width: 18%;">
      <div class="companyTree">
        <div class="title">组织架构</div>
        <div class="tree">
          <el-input class="search" v-model="filterText" placeholder :suffix-icon="Search" />
          <el-tree ref="treeRef" class="filter-tree" :data="companyData" :props="defaultProps" default-expand-all
            :filter-node-method="filterNode" @node-click="handleNodeClick" highlight-current>
            <template #default="{ node, data }">
              <span class="custom-tree-node">
                <span>{{ node.label }}</span>
                <!--<span class="oper">
                  <img :src="image.rapCompanyAdd" @click="e => handleAppend(data, e)" />
                  <img :src="image.rapCompanyEdit" @click="e => handleUpdate(data, e)" />
                  <img :src="image.rapCompanyDelete" @click="e => handleRemove(data, e)" />
                </span>-->
              </span>
            </template>
          </el-tree>
        </div>
      </div>
    </div>
    <div style="float: left; width: 82%; height: auto">
      <layout-card v-model="search" :filters="exampleOptions" headline="信息列表" headtitle="数据筛选" :hasButton="true"
        @search-change="getData" @search-reset="resetGetData">
        <template #action>
          <el-button type="primary" @click="handleCreate">添加设备类型</el-button>
        </template>

        <table-common :loading="loading" :columns="exampleColumns" :pagination="pager" :table-data="data" size="large"
          @sort-change="handleSortChange" @current-change="myChangeCurrent" @size-change="myChangePageSize"
          :row-key="getRowKey" lazy :load="load" :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
          stripe>
          <template #action="{ row }">
            <!-- 自定义操作栏示例  -->
            <el-button class="link-btn" link type="primary" @click="handleAddChildren(row)">添加子类</el-button>
            <el-button class="link-btn" @click="handleEdit(row)" link type="primary">编辑</el-button>
            <el-popconfirm v-if="row.children.length === 0" title="是否确定删除?" confirmButtonText="确定" cancelButtonText="取消" @confirm="() => handleDelete(row)">
              <template #reference>
                <el-button class="link-btn" link type="danger">删除</el-button>
              </template>
            </el-popconfirm>
            <el-text v-else>  </el-text>
          </template>
        </table-common>
      </layout-card>
    </div>
  </div>
  <edit-dialog :centerDialogVisible="centerDialogVisible" :tilte="addTilte" :key="timer" @Cancel="Cancel"
    @Submit="Submit">
    <template #content>
      <FilterBar ref="addoptions" :rules="myRules" :filters="dialogType" :hasButton="false"></FilterBar>
    </template>
  </edit-dialog>
</template>

<script lang="ts" setup>
// 需要导入watch监听
import { computed, ref, onBeforeMount, watch, reactive, nextTick } from 'vue'
// 以下两项需要导入
import { ElTree, ElMessage } from 'element-plus'
import { Search } from '@element-plus/icons-vue'
// 7-18修改LayoutCard 页面，hasButton参数为false时显示为弹窗样式，为true时显示为搜索栏样式
import LayoutCard from '@/components/LayoutCard/index.vue'
import TableCommon from '@/components/TableCommon/index.vue'
import { exampleColumns } from '../config/columns'
import { getResource } from '@/api/resource'
import { useStore } from 'vuex'
import FilterBar from '@/components/FilterBar/index.vue'
import {
  exampleOptions,
  dialogEditOptions,
  dialogOptions,
  dialogAddChildrenOptions
} from '../config/filters'
import { usePagination } from 'vue-request'
import editDialog from '@/components/editDialog/index.vue'
import {
  addeEqptPage,
  eqptPageDelete,
  getFindTree,
  upDatePage
} from '@/api/eqpt/type'

// =============模拟接口数据-START
// 此处是模拟的接口返回数据，项目中请用`@/api/`下接口代替，删除当前代码！
const Service = () => {
  return new Promise(() => {
    //
  })
}
// =============模拟接口数据==END

const {
  run,
  data,
  loading,
  current,
  pageSize,
  total,
  changeCurrent,
  changePageSize
} = usePagination(Service, {
  manual: true,
  pagination: {
    currentKey: 'pageNum',
    pageSizeKey: 'pageSize',
    totalKey: 'data.total'
  }
})

// 存储每一行的id
const expandedRowKeys = ref([])
/**
 * 用于循环遍历存储可展开行的标识符
 * @param rows tableData绑定的数据
 */
const calculateExpandedRowKeys = (rows) => {
  let expandedKeys = []
  rows.forEach((row) => {
    if (row.children && row.children.length > 0) {
      expandedKeys.push(row.typeId)
      expandedKeys = expandedKeys.concat(
        calculateExpandedRowKeys(row.children)
      )
    }
  })
  return expandedKeys
}
/**
 * 获取每一数据的唯一标识符
 * @param row 每一行的数据
 */
const getRowKey = (row) => {
  return row.typeId // 假设你的数据中每行都有唯一的typeId字段
}

// 封装控件类型 用于使用数据字典重写terminal
const exampleOptions1 = ref(exampleOptions)

// 定义一个我的total
const myTotal = ref(0)

// 新增弹窗是否打开
const centerDialogVisible = ref(false)
// 弹窗标题
const addTilte = ref('新增问题类型')
// 弹窗页面类型
const dialogType = ref()
// 时间戳，用于确保弹窗页面能加载不同的界面
const timer = ref()
// const visible = ref(false)
// const isAdd = ref(true)
// const handleCreate = () => {
//   isAdd.value = true
//   visible.value = true
// }
// 7-17------------------

/**
 * author 万德渝
 * date  2023-7-29
 * 页面组件绑定动态数据
 */

// 打开新增窗口
const handleCreate = () => {
  timer.value = new Date().getTime()
  dialogType.value = dialogOptions
  // 重写里面的terminal  获取数据字典获取的值
  dialogType.value.forEach((e) => {
    if (e.prop == 'terminal') {
      e.inputProps.options = exampleOptions1.value[1].inputProps.options
    } else if (e.prop == 'tree') {
      e.inputProps.data = companyData.value
    } else if (e.prop == 'parentTypeId') {
      e.defaultValue = '无'
    }
  })
  addTilte.value = '添加设备类型'
  centerDialogVisible.value = true
}

// 添加子类
// 存储当前设备的id
const equipmentId = ref('')

/** 添加子类回调
 * row 代表当前行
 */
const handleAddChildren = (row) => {

  equipmentId.value = row.typeId
  timer.value = new Date().getTime()
  dialogType.value = dialogAddChildrenOptions
  // 重写里面的terminal  获取数据字典获取的值
  dialogType.value.forEach((e) => {
    if (e.prop == 'terminal') {
      e.inputProps.options = exampleOptions1.value[1].inputProps.options
      e.defaultValue = row.terminal
    } else if (e.prop == 'tree') {
      e.defaultValue = ownersCopy.value.organName
    } else if (e.prop == 'parentTypeId') {
      e.defaultValue = row.typeName
    }
  })
  addTilte.value = '添加子类设备'
  centerDialogVisible.value = true
}

// 以下为树控件必须的部分
const defaultProps = {
  children: 'children',
  label: 'label'
}
const filterText = ref('')
// 定义树的实例
const treeRef = ref<InstanceType<typeof ElTree>>()

watch(filterText, (val) => {
  treeRef.value!.filter(val)
})

interface Tree {
  [key: string]: any
}

// 请求用户的权限树
const { getters } = useStore()
// 拿到vuex里面用户的信息
const UserInfo = computed(() => getters['user/getOrganTree'])
const Users = computed(() => getters['user/getUserInfo'])
const authOrganIds = computed(() => getters['user/getAuthOrganIds'])
// 用户信息
const creator = ref({})
creator.value.id = Users.value.userId
creator.value.name = Users.value.userName
// 中间变量存储父级id label
const parentClassName = ref({})
// 中间变量存储 当前科室信息 ownersCopy
const ownersCopy = ref({})

// 对树进行格式化
function convertData(data) {
  const result = []

  function traverse(node) {
    const newNode = {
      id: node.data.organId,
      label: node.data.name,
      value: node.data.organId,
      children: []
    }

    if (node.children.length > 0) {
      node.children.forEach((child) => {
        newNode.children.push(traverse(child))
      })
    }

    return newNode
  }

  data.forEach((node) => {
    result.push(traverse(node))
  })

  const rootNode = {
    id: 'root',
    label: '全部',
    value: 'root',
    children: result
  }

  return [rootNode]
}
const formatTreeData = convertData(UserInfo.value)

const companyData = ref<Tree[]>(formatTreeData)
// 树节点被点击
const handleNodeClick = (data, node) => {
  if (node.isLeaf) {
    parentClassName.value = node.parent.data
    ownersCopy.value.organId = data.id
    ownersCopy.value.organName = data.label
    search.value = { ...search.value, owner: { organId: data.id } }
    getData()
  }
}
// 搜索过滤
const filterNode = (value: string, data: Tree) => {
  if (!value) return true
  return data.label.includes(value)
}
// 定义中间变量存储row当前行的值
const currentRow = ref({})
// 以上为树控件必须的部分
const handleEdit = (row) => {
  dialogType.value = dialogEditOptions
  // 该循环用于进行编辑页面数据回显，需要字段对应
  dialogEditOptions.forEach((e) => {
    if (row[e.prop] != null) {
      e.defaultValue = row[e.prop]
    }
  })
  dialogType.value.forEach((e) => {
    if (e.prop == 'terminal') {
      e.inputProps.options = exampleOptions1.value[1].inputProps.options
    } else if (e.prop == 'parentTypeId') {
      e.defaultValue = '无'
    } else if (e.prop == 'tree') {
      e.defaultValue = ownersCopy.value.organName
    }
  })

  timer.value = new Date().getTime()
  addTilte.value = '编辑设备类型'
  centerDialogVisible.value = true

  currentRow.value = row
}
// 新增窗口点击取消
const Cancel = () => {
  centerDialogVisible.value = false
  dialogType.value = ''
}

// 递归得到弹出框中的树形下拉框value对应的对象
function findNodeById(data, targetId) {
  for (const node of data) {
    if (node.id === targetId) {
      return node
    }
    if (node.children.length > 0) {
      const foundNode = findNodeById(node.children, targetId)
      if (foundNode) {
        return foundNode
      }
    }
  }
  return null
}

const addoptions = ref({})
// 新增窗口点击确认
const Submit = async () => {
  const { typeName } = addoptions.value.getParams()
  const newtypename = typeName ? typeName.replace(/\s+/g, '') : typeName
  await nextTick(() => {
    addoptions.value.setFieldsValue({
      typeName: newtypename
    })
  })
  if (addTilte.value === '编辑设备类型') {
    const addParams = ref({})
    addParams.value = addoptions.value.getParams()
    const updateParamsData = ref({
      typeId: currentRow.value.typeId,
      parentTypeId: currentRow.value.parentTypeId,
      typeName: addParams.value.typeName,
      terminal: addParams.value.terminal,
      lastMender: creator.value
    })
    const flag1 = await addoptions.value?.validateRuleFormRef()
    if (flag1 === true) {
      upDatePage(updateParamsData.value).then((res) => {
        if (res.code == 1) {
          ElMessage.success('编辑成功')
          getData()
          centerDialogVisible.value = false
        } else {
          getData()
          centerDialogVisible.value = false
          ElMessage.error('编辑失败，已存在该设备')
        }
      })
    }
  } else {
    const flag1 = await addoptions.value?.validateRuleFormRef()
    if (flag1 == true) {
      const addParams = ref({})
      addParams.value = addoptions.value.getParams()
      if (addParams.value.parentTypeId == '无') {
        const targetNode = findNodeById(companyData.value, addParams.value.tree)
        addParams.value.parentTypeId = 0
      } else {
        const targetNode = findNodeById(
          companyData.value,
          ownersCopy.value.organId
        )
        addParams.value.parentTypeId = equipmentId.value
      }
      addParams.value.creator = creator.value
      // 执行提交逻辑
      addParams.value.owners = [
        {
          organId: targetNode.id,
          organName: targetNode.label
        }
      ]
      delete addParams.value.tree

      // 调用增加接口
      addeEqptPage(addParams.value).then((res) => {
        getData()
        if (res.code == 0) {
          ElMessage.error(`${res.message}`)
        } else if (res.code == 1) {
          ElMessage.success('添加成功')
          centerDialogVisible.value = false
        }
      })
    }
  }
}

// 删除
/** author 熊灿
 * date 72023-7-29
 *row 当前行
 */
const handleDelete = (row: any) => {

  eqptPageDelete({ typeId: `${row.typeId}` }).then((res) => {
    if (res.code == 1) {
      ElMessage.success('删除成功')
      getData()
    } else {
      ElMessage.error('删除失败')
    }
  })
}

// 7-17------------------
const pager = computed(() => ({
  currentPage: current.value,
  pageSize: pageSize.value,
  // pageSize: 20,
  // total: total.value,
  total: myTotal.value,
  pageCount: Math.ceil(myTotal.value / pageSize.value) === 0 ? 1 : Math.ceil(myTotal.value / pageSize.value)
}))
const search = ref({})

// 自定义重写
const resetGetData = (data: FilterDataType) => {
  search.value = data

  getData()
}
// 获取数据
const getData = () => {
  const params = {
    pageNum: current.value,
    pageSize: pageSize.value,
    condition: {
      ...search.value,
      // owner: { organId: ownersCopy.value.organId },
      owners: [ownersCopy.value.organId]
    }
  }

  getFindTree(params).then((res) => {
    data.value = res.data.list
    myTotal.value = res.data.total
    expandedRowKeys.value = calculateExpandedRowKeys(data.value)
  })

  run(params)
  loading.value = false
}
// 循环递归查找第一个叶节点
const printFirstLeafNode = () => {
  let firstLeafNode = null

  const findFirstLeafNode = (node) => {
    if (node.children.length === 0) {
      firstLeafNode = node
      return node // 返回node
    }
    return findFirstLeafNode(node.children[0]) // 返回递归调用的结果
  }

  if (companyData.value.length > 0) {
    firstLeafNode = findFirstLeafNode(companyData.value[0])
  }

  return firstLeafNode
}

// 重写排序方法
const handleSortChange = (column: any) => {
  const prop = column.prop
  let order = column.order
  if (order === 'descending') {
    order = 'DESC'
  } else if (order === 'ascending') {
    order = 'ASC'
  }
  search.value.order = [{ column: prop, method: order }]
  getData()
}

// 重写方法当前页大小
const myChangePageSize = (value: any) => {
  changePageSize(value)
  getData()
}
// 重写方法当前页
const myChangeCurrent = (value: any) => {
  changeCurrent(value)
  getData()
}

// 请求航站楼数据getResource
onBeforeMount(() => {
  const result = printFirstLeafNode()
  // console.log('result.idresult.idresult.idresult.id',result.id);
  //9.13 解决页面初始化 点击操作按钮弹出框回显内容没有所属科室问题
  ownersCopy.value.organId = result.id
  ownersCopy.value.organName = result.label
  getResource('terminal').then((res) => {
    exampleOptions1.value.forEach((e) => {
      if (e.prop == 'terminal') {
        // 这部分数据应该由接口获取
        // 刚进入页面和点击清空时，应把选择情况清空
        e.inputProps.options = res.data.properties.meta.reverse()
        // 手动重写单选按钮点击事件
      }
    })
  })
})

// typeName: '213123', terminal: 'T3', tree: '1130882853052088320'
// 定义验证的正则表达式
const myRules = reactive({
  typeName: [{
    required: true,
    message: '请填写设备类型',
    trigger: 'change',
  },
  {
    max: 10, message: "设备类型名称长度不能大于10", trigger: "change",
  },
  {
    max: 10, message: "设备类型名称长度不能大于10", trigger: "change",
    validator: (rule: any, value: any, callback: any) => {
      if (value) value = value.replace(/\s+/g, '')
      callback()
    }
  }
  ],
  terminal: [{ required: true, message: '请勾选航站楼', trigger: 'blur' }],
  tree: [{ required: true, message: '请选择归属科室', trigger: 'blur' }]
})

</script>
<style lang="less" scoped>
.container {
  display: flex;
  align-items: stretch;
  justify-content: center;
  background: #f5f7f9;
  min-height: 100%;
  overflow: hidden;

  .companyTree {
    padding: 24px;
    margin: 12px 0 24px 24px;
    background: #fff;
    border-radius: 8px;

    .title {
      font-size: 16px;
      font-family: HarmonyOS_Sans_SC_Medium;
      border-left: #2f7df1 2px solid;
      text-indent: 1em;
      color: #353a42;
      line-height: 16px;
      margin: 10px 0;
    }

    .search {
      margin-bottom: 20px;
    }

    /deep/ .el-tree-node__content {
      height: 32px;
    }

    /deep/ .el-tree--highlight-current .el-tree-node.is-current>.el-tree-node__content {
      background-color: #5daaf0; //背景色
    }

    .custom-tree-node {
      flex: 1;
      display: flex;
      align-items: center;
      justify-content: space-between;
      font-size: 14px;
      padding-right: 8px;

      .oper {
        display: flex;
        justify-content: center;
        align-items: center;
        user-select: none;

        img {
          width: 20px;
          height: 20px;
          object-fit: contain;

          &:hover {
            transform: scale(1.1);
          }
        }

        img+img {
          margin-left: 8px;
        }

        .border {
          border-radius: 4px;
          border: 1px solid #2f7df1;
          padding: 2px;
          box-sizing: border-box;
          margin-left: 8px;
        }
      }
    }
  }
}
</style>
